package com.xingda.packing.rule.choose;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xingda.packing.domain.PackDemandRange;
import com.xingda.packing.domain.ProductBox;
import com.xingda.packing.domain.Wheel;
import com.xingda.packing.enums.BoxTaskType;
import com.xingda.packing.minitor.entity.PkTaskInfo;
import com.xingda.packing.minitor.entity.PkWheel;
import com.xingda.packing.minitor.mapper.PkTaskInfoMapper;
import com.xingda.packing.minitor.mapper.PkWheelMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Order(10)
@Component
@Slf4j
public class LayerTorsionChoose implements ChooseService {

    @Resource
    PkTaskInfoMapper pkTaskInfoMapper;

    @Resource
    PkWheelMapper pkWheelMapper;

    @Override
    public boolean canChoose(ProductBox productBox, Wheel wheel) {
        boolean result = can(productBox, wheel);
        if (!result) {
            log.info("box:{}, 工字轮条码：{}，层扭转和检查:{}", productBox.getBoxNo(), wheel.getBarCode(), false);
        }
        return result;
    }

    private boolean can(ProductBox productBox, Wheel wheel) {
        if (productBox.getType() == BoxTaskType.PACKING_CLEAN.getTypeId()) {
            return true;
        }
        if (productBox.getType() == BoxTaskType.PACKING_SEMI_FINISHED_DISQUALITY.getTypeId()) {
            return true;
        }
        if (!productBox.getPackDemand().getFloorTorsion().isEnable()) {
            return true;
        }

        LambdaQueryWrapper<PkTaskInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PkTaskInfo::getTaskId, productBox.getTaskId()).orderByDesc(PkTaskInfo::getLayer);
        List<PkTaskInfo> pkTaskInfoList = pkTaskInfoMapper.selectList(wrapper);

        int wheelCount = pkTaskInfoList.size() + 1;
        log.info("box:{}, 工字轮条码:{}，开始检查层扭转和:{}", productBox.getBoxNo(), wheel.getBarCode(), wheelCount);

        //当前装箱个数加上当前工字轮，是否等于需求个数或者是当前层的最后一个，如果是，则需要额外判断层扭转和是否满足
        if (wheelCount == productBox.getRequireCount() || wheelCount % productBox.getFloorLocationCount() == 0) {
            int maxLayer = pkTaskInfoList.stream().mapToInt(PkTaskInfo::getLayer).max().orElse(0);

            List<Integer> wheelIds = pkTaskInfoList.stream().filter(p -> p.getLayer() == maxLayer).
                    map(PkTaskInfo::getWheelId).collect(Collectors.toList());

            LambdaQueryWrapper<PkWheel> wheelWrapper = new LambdaQueryWrapper<>();
            wheelWrapper.in(PkWheel::getId, wheelIds);
            List<PkWheel> pkWheels = pkWheelMapper.selectList(wheelWrapper);
            BigDecimal torqueValue = pkWheels.stream().map(PkWheel::getTorqueValue).filter(Objects::nonNull).
                    reduce(BigDecimal.ZERO,BigDecimal::add).add(wheel.getTorsionValue());

            PackDemandRange torqueDemand = productBox.getPackDemand().getFloorTorsion();
            log.info("当前箱[{}]层扭转和[{}]检查[{}~{}]", productBox.getBoxNo(), torqueValue,
                    torqueDemand.getMin(), torqueDemand.getMax());

            return torqueValue.compareTo(torqueDemand.getMax()) <= 0 && torqueValue.compareTo(torqueDemand.getMin()) >= 0;
        }
        return true;
    }
}
